package cn.tedu.store.service.impl;

import java.util.Date;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import cn.tedu.store.entity.User;
import cn.tedu.store.mapper.UserMapper;
import cn.tedu.store.service.IUserService;
import cn.tedu.store.service.ex.InsertException;
import cn.tedu.store.service.ex.PasswordNotMatchException;
import cn.tedu.store.service.ex.UpdateException;
import cn.tedu.store.service.ex.UserNotFoundException;
import cn.tedu.store.service.ex.UsernameConflictException;
import jdk.nashorn.internal.runtime.FindProperty;

/**
 * 业务接口实现类
 * 
 * @author DELL
 *
 */
@Service
public class UserServiceImpl implements IUserService {

	@Autowired
	private UserMapper userMapper;

	@Override
	public void reg(User user) {
		// 从参数user对象中获取用户名
		String username = user.getUsername();
		// 调用userMapper根据用户名查询用户数据
		User result = userMapper.findByUsername(username);
		// 判断查询结果是否不为null
		if (result != null) {
			// 是：用户名存在，不允许注册，抛出UsernameConflictException异常
			throw new UsernameConflictException(result.getUsername());
		}
		// 参数user是客户端提交的注册数据，并不包含隐藏数据
		// 执行加密
		String salt = UUID.randomUUID().toString().toUpperCase();
		String Md5Password = getMD5Password(user.getPassword(), salt);
		// 补全数据：salt
		user.setSalt(salt);
		// 补全数据：加密后的密码
		user.setPassword(Md5Password);
		// 补全数据：is_delete，值为0
		user.setIsDelete(0);
		// 补全数据：4项日志，用户名为注册的用户名，时间为当前时间
		Date now = new Date();
		user.setCreatedUser(username);
		user.setCreatedTime(now);
		user.setModifiedUser(username);
		user.setModifiedTime(now);
		// 调用userMapper的功能插入用户数据，实现注册，并获取插入数据时的返回值
		Integer row = userMapper.insert(user);
		// 判断以上返回值是否不唯一
		if (row != 1) {
			// 是：插入用户数据失败，抛出InsertException异常
			throw new InsertException("注册失败，发生未知错误！");
		}

	}
	/**
	 * 用户登录
	 */
	@Override
	public User login(String username, String password) {
		//根据username参数查询用户数据
		User result = userMapper.findByUsername(username);
		//判断查询结果是否为null
		if(result == null) {
			//是：用户名不存在，抛出UserNotFoundException
			throw new UserNotFoundException(result.getUsername());
		}

		//判断查询结果中的isDelete是否为1
		if(result.getIsDelete().equals(1)) {
			//是则标记为已删除，抛出UserNotFoundException
			throw new UserNotFoundException(result.getUsername());
		}

		//从查询中查看 salt
		String salt = result.getSalt();
		
		String md5Password = getMD5Password(password, salt);
		
		if(!result.getPassword().equals(md5Password)) {
			throw new PasswordNotMatchException();
		}
		result.setSalt(null);
		result.setIsDelete(null);
		result.setCreatedUser(null);
		result.setCreatedTime(null);
		result.setModifiedUser(null);
		result.setModifiedTime(null);
		result.setPassword(null);
		
		return result;
	}
	
	@Override
	public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
		// 根据参数uid查询用户数据
			User result = userMapper.findByUid(uid);
	    // 判断查询结果是否为null
			if(result == null) {
				// 是：用户数据不存在，抛出UserNotFoundException
				throw new UserNotFoundException(result.getUsername());
			}
	    

	    // 判断查询结果中的isDelete是否为1
			if(result.getIsDelete().equals(1)) {
				// 是：用户被标记为已删除，抛出UserNotFoundException
				throw new UserNotFoundException(result.getUsername());
			}
	    

	    // 取出查询结果中的盐值
			String salt = result.getSalt();
	    // 将参数oldPassword进行加密，得到oldMd5Password
			String oldMD5Password = getMD5Password(oldPassword, salt);
	    // 判断查询结果中的password与oldMd5Password是否不匹配
			if(!result.getPassword().equals(oldMD5Password)) {
				// 是：密码验证失败，抛出PasswordNotMatchException
				throw new PasswordNotMatchException("密码错误");
			}
	    

	    // 将参数newPassword进行加密，得到newMd5Password
			String newMD5Password =getMD5Password(newPassword, salt);
	    // 执行更新密码，获取返回值
			Integer rows = userMapper.UpdatePassword(uid, newMD5Password,username, new Date());
	    // 判断返回的受影响的行数是否不为1
			if(!rows.equals(1)) {
				// 是：更新失败，抛出UpdateException
				throw new UpdateException("更新数据时发生未知错误！");
			}
	    
		
	}
	
	
	@Override
	public void changeInfo(Integer uid,String username,User user) {
		//通过参数uid查询用户数据
		User result = userMapper.findByUid(uid);
		//判断查询结果是否为null
		if(result == null) {
			//是：用户数据不存在，抛出UserNotFoundException
			throw new UserNotFoundException();
		}
		//判断查询结果中的isDelete是否为1
		if(result.getIsDelete().equals(1)) {
			//是：用户数据被标记为已删除，抛出UserNotFoundException
			throw new UserNotFoundException();
		}
		
		//将参数uid封装到参数user的uid中
		user.setUid(uid);

		//将参数username封装到参数user的ModifiedUser中
		user.setModifiedUser(username);
		//创建时间对象，封装到参数user的modifiedTime中
		user.setModifiedTime(new Date());
		//执行修改，并获取返回值
		Integer rows = userMapper.UpdateInfo(user);
		//判断返回的受影响的行数是否不为1
		if(rows != 1) {
			//是：更新错误，抛出UpdateException
			throw new UpdateException("修改失败！");
		}
		
		
	}
	
	@Override
	public void changeAvatar(Integer uid, String username, String avatar) {
		//通过参数uid获取用户信息
		User user = userMapper.findByUid(uid);
		//判断是否为null  是则抛出 用户不存在异常
		if(user == null) {
			throw new UserNotFoundException("用户不存在！");
		}
		//判断isDelete 是否为1 是则抛出用户已经删除异常
		if(user.getIsDelete().equals(1)) {
			throw new UserNotFoundException("用户已删除！");
		}
		//执行修改头像 并且获取返回值
		Integer row = userMapper.UpdateAvatar(uid, avatar, username,new Date());
		//判断返回值是否不为1 抛出修改失败异常
		if(row !=1) {
			throw new UpdateException("修改失败");
		}
	}
	
	/**
	 * 
	 */
	@Override
	public User getByUid(Integer uid) {
		 // 通过参数uid查询用户数据
		User result = userMapper.findByUid(uid);
	    // 判断查询结果是否为null // 判断查询结果中的isDelete是否为1
		if(result == null || result.getIsDelete().equals(1)) {
			// 是：用户数据不存在，抛出UserNotFoundException
			throw new UserNotFoundException();
		}

	    // 创建新的User对象
		User user = new User();
		
	    // 将查询结果中的username,gender,phone,email封装到新对象中
		user.setUsername(result.getUsername());
		user.setEmail(result.getEmail());
		user.setGender(result.getGender());
		user.setPhone(result.getPhone());
	    // 返回新对象

		return user;
	}
	
	

	/**
	 * 密码加密
	 * 
	 * @param password 原密码
	 * @param slat     盐值
	 * @return 返回 加密后的密码
	 */
	public String getMD5Password(String password, String salt) {
		// 加密规则：在原密码的左侧和右侧均拼接盐值，循环加密
		String str = salt + password + salt;
		for (int i = 0; i < 5; i++) {
			str = DigestUtils.md5DigestAsHex(str.getBytes()).toUpperCase();
		}
		return str;
	}
	
	
	
	

}
